package cn.com.dashihui.shiro;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;

import com.jfinal.core.JFinal;
import com.jfinal.kit.JsonKit;

import cn.com.dashihui.kit.CommonKit;
import cn.com.dashihui.web.domain.AjaxResult;

/**
 * 本Filter过滤作为基础shiro过滤器，但只对“是否认证”进行判断，Controller Action的认证交给ShiroInterceptor
 * @author RANCE
 */
public class GlobalAuthorizationFilter extends AuthorizationFilter {
	
	/**
	 * 认证不通过时
	 */
	@Override
	protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
		if(CommonKit.isAjax((HttpServletRequest)request)){
			PrintWriter out = response.getWriter();
			out.print(JsonKit.toJson(new AjaxResult(-2)));
			return false;
		}else{
			return super.onAccessDenied(request, response);
		}
	}
	
	@Override
	protected boolean isAccessAllowed(ServletRequest req,ServletResponse res, Object mappedValue) throws Exception {
		//判断如果是controller的action，则放过，将由ShiroInterceptor拦截并处理
		//如果不在此判断，有可能同一个action会判断两次
		if(isAction((HttpServletRequest)req)){
			return true;
		}
		//判断当前是否有用户认证通过
		Subject currentUser = getSubject(req, res);
		return currentUser!=null&&currentUser.isAuthenticated();
	}
	
	/*
	 * 判断当前请求的URI是否是controller的action
	 * 以下代码取自JFinal的JFinal.core的相关类，保证与JFinal获取AK的方式相同
	 */
	private boolean isAction(HttpServletRequest request){
		//获取配置在jFinal中的所有action key
		List<String> aks = JFinal.me().getAllActionKeys();
		//获取请求的URI并截掉contextPath部分
		String target = request.getRequestURI();
		String contextPath = request.getServletContext().getContextPath();
		Integer contextPathLength = (contextPath == null || "/".equals(contextPath) ? 0 : contextPath.length());
		if (contextPathLength != 0){
			target = target.substring(contextPathLength);
		}
		//判断是否是action
		return aks.contains(target);
	}
}
